﻿using System;
using System.ServiceModel;
using Microsoft.Practices.Unity;
using Sern.Abstracts.Common;
using Sern.Abstracts.Tracker.ServiceContracts;
using Sern.Common;
using Sern.ServiceImplementation.MapReduce;

namespace Sern.ServiceImplementation
{
    public static class MapReduceProxyFactory<TClient, TKey,TVal>
        where TClient : IMapReduce<TKey, TVal>
    {
        public static IClient<TClient> CreateMapReduceProxy(Func<IClient<ITracker>> trackerFactory,  TKey key)
            
        {
            using (IClient<ITracker> tracker = trackerFactory())
            {
                var clientType = ComponentLocator.Unity.Resolve<IClientTypeToEnumMapper>()[typeof (TClient)];
                var jobId = ComponentLocator.Unity.Resolve<Guid>("ClientJobId");

                var filterClientInfo = tracker.Proxy.FindActiveClientInfo(jobId, clientType,
                                                                            key.GetHashGuid(),
                                                                            key.GetRedundancyKeyHash(),
                                                                            typeof (TKey).FullName,
                                                                            typeof (TVal).FullName);
                var bindingInfo = ComponentLocator.Unity.Resolve<IBindingFactory>()[clientType]();

                var channelFactory = new ChannelFactory<TClient>(bindingInfo.Binding, filterClientInfo.Uri);
                return channelFactory.CreateChannel().Wrap();
                
            }
        }

        public static IClient<TClient> CreateMapReduceProxy(Func<IClient<ITracker>> trackerFactory)
        {
            using (IClient<ITracker> tracker = trackerFactory())
            {
                var clientType = ComponentLocator.Unity.Resolve<IClientTypeToEnumMapper>()[typeof(TClient)];
                var jobId = ComponentLocator.Unity.Resolve<Guid>("ClientJobId");

                var filterClientInfo = tracker.Proxy.FindActiveClientInfo(jobId, clientType,
                                                                            Guid.Empty,
                                                                            Guid.Empty,
                                                                            typeof(TKey).FullName,
                                                                            typeof(TVal).FullName);
                var bindingInfo = ComponentLocator.Unity.Resolve<IBindingFactory>()[clientType]();

                var channelFactory = new ChannelFactory<TClient>(bindingInfo.Binding, filterClientInfo.Uri);
                return channelFactory.CreateChannel().Wrap();

            }
        }

        
    }
}
